package com.yubest.shiro.config;

import com.yubest.shiro.service.shiro.MyFormAuthenticationFilter;
import com.yubest.shiro.service.shiro.MyRealm;
import com.yubest.shiro.service.shiro.MySessionDAO;
import com.yubest.shiro.service.shiro.MySessionManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 配置类
 *
 * @Author: hweiyu
 * @Date: 2022/11/7 11:46
 */
@Configuration
public class ShiroConfig {

    @Value("${ignoreUris}")
    private String[] ignoreUris;

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //登陆，权限校验类
        MyRealm realm = new MyRealm();
        //散列算法，这里使用MD5算法进行密钥校验
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        realm.setCredentialsMatcher(matcher);
        securityManager.setRealm(realm);

        MySessionManager sessionManager = new MySessionManager();
        sessionManager.setSessionDAO(new MySessionDAO());
        securityManager.setSessionManager(sessionManager);

        return securityManager;
    }

    /**
     * 开启Shiro aop注解模式
     *
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        sourceAdvisor.setSecurityManager(securityManager());
        return sourceAdvisor;
    }

    /**
     * 路径过滤规则
     *
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());

        //自定义filter
        LinkedHashMap<String, Filter> filterMap = new LinkedHashMap<>();
        // 这里使用自定义的filter，替换原来的 FormAuthenticationFilter
        filterMap.put("authc", new MyFormAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        shiroFilterFactoryBean.setLoginUrl("/login");

        Map<String, String> map = new LinkedHashMap<>();
        // 允许匿名访问
        for (String uri : ignoreUris) {
            map.put(uri, "anon");
        }
        // 进行权限校验
        map.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

}
